/*
   Copyright (c) 2005 Lucas Mello Schnorr <schnorr@gmail.com>
   
   This file is part of DIMVisual.
   
   DIMVisual is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.
   
   DIMVisual is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   for more details.
   
   You should have received a copy of the GNU Lesser General Public License
   along with DIMVisual; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include "MPIRASTROConverter.h"

@implementation MPIRASTROConverter
- (id) initWithProvider: (id<Integrator>) prov
{
	self = [super init];
	NSArray *ret;

	stack = [[NSMutableDictionary alloc] init];
	stackRecv = [[NSMutableDictionary alloc] init];
	nodeMachine = [[NSMutableDictionary alloc] init];
	provider = prov;
	/* check if hierarchy is 'ok' for mpi */

	return self;
}

- (PajeSetState *) addPajeSetState: (NSString *) state time: (NSString *) time 
container: (NSString *) container
{
	PajeSetState *set = [[PajeSetState alloc] initWithTime: time];
	[set setEntityType: [provider aliasToName: @"MPIState"]];
	[set setValue: [provider aliasToName: state]];
	[set setContainer: container];
	[set autorelease];
	return set;
}


- (id) convertEvent: (GEvent *) event
{
	NSMutableArray *ret = nil;
	NSString *container;
	int type;
	
	ret = [[NSMutableArray alloc] init];

	GFields *f = [event fields];
	NSString *machine, *thread, *identifier;

	machine = [[f fieldWithSimpleStringKey:@"machine"] description];
	thread = [[f fieldWithSimpleStringKey: @"thread"] description];
	identifier = [[event identifier] description];


	container = [provider identifierForEntity: 
		[NSArray arrayWithObjects: @"Machine", @"Thread", nil]
				ids:
		[NSArray arrayWithObjects: machine, thread, nil]];

	if (container == nil){
		[ret release];
		return nil;
	}
	
	type = atoi ([identifier cString]);

	if (type == MPI_COMM_SPAWN_IN || type == MPI_COMM_SPAWN_OUT ||
		type == MPI_INIT || type == MPI_FINALIZE){
		[ret addObjectsFromArray: 
			[self convertEventMPI2: event]];
	}else 
	/**
	 * BCAST
	 * 
	 */
	if (type == MPI_BCAST_IN || type == MPI_BCAST_OUT){
		[ret addObjectsFromArray: [self convertEventBcast: event]];
		
	/**
	 * SENDRECV
	 * 
	 */
	}else if (type == MPI_SEND || type == MPI_RECV
		||type == MPI_BSEND_IN
		||type == MPI_BSEND_INIT_IN
		||type == MPI_RECV_INIT_IN
		||type == MPI_SEND_INIT_IN
		||type == MPI_IBSEND_IN
		||type == MPI_IRECV_IN
		||type == MPI_IRSEND_IN
		||type == MPI_ISEND_IN
		||type == MPI_ISSEND_IN
		||type == MPI_RSEND_IN
		||type == MPI_RSEND_INIT_IN
		||type == MPI_SENDRECV_IN
		||type == MPI_SENDRECV_REPLACE_IN
		||type == MPI_SSEND_IN
		||type == MPI_SSEND_INIT_IN
		||type == MPI_WAIT_IN
		||type == MPI_WAITALL_IN
		||type == MPI_WAITANY_IN
		||type == MPI_WAITSOME_IN
		|| type == MPI_IRECV_OUT
		|| type == MPI_IRSEND_OUT
		|| type == MPI_BSEND_OUT
		|| type == MPI_BSEND_INIT_OUT
		|| type == MPI_RECV_INIT_OUT
		|| type == MPI_SEND_INIT_OUT
		|| type == MPI_IBSEND_OUT
		|| type == MPI_ISEND_OUT
		|| type == MPI_ISSEND_OUT
		|| type == MPI_RSEND_OUT
		|| type == MPI_RSEND_INIT_OUT
		|| type == MPI_SENDRECV_OUT
		|| type == MPI_SENDRECV_REPLACE_OUT
		|| type == MPI_SSEND_OUT
		|| type == MPI_SSEND_INIT_OUT
		|| type == MPI_WAIT_OUT
		|| type == MPI_WAITALL_OUT
		|| type == MPI_WAITANY_OUT
		|| type == MPI_WAITSOME_OUT
		||type == MPI_SEND_IN
		|| type == MPI_SEND_OUT
		|| type == MPI_RECV_OUT
		||type == MPI_RECV_IN){
		[ret addObjectsFromArray:
			[self convertEventSendRecv: event]];

	/**
	 * GATHER
	 * 
	 */
	}else if (type == MPI_ALLGATHER_IN ||
		type == MPI_ALLGATHERV_IN ||
		type == MPI_GATHER_IN ||
			type == MPI_ALLGATHER_OUT  ||
		 type == MPI_ALLGATHERV_OUT ||
		 type == MPI_GATHER_OUT){
		[ret addObjectsFromArray: [self convertEventGather: event]];

	/**
	 * REDUCE
	 * 
	 */
	}else if (type == MPI_ALLREDUCE_IN
		|| type == MPI_ALLREDUCE_OUT
		|| type == MPI_REDUCE_SCATTER_OUT
		|| type == MPI_REDUCE_OUT
		|| type == MPI_REDUCE_SCATTER_IN
		|| type == MPI_REDUCE_IN){
//		[ret addObjectsFromArray: [self convertEventReduce: event]];
		

	/**
	 * SCATTER
	 * 
	 */
	}else if (type == MPI_SCATTER_IN ||
		type == MPI_SCATTERV_IN 
		|| type == MPI_SCATTER_OUT
		|| type == MPI_SCATTERV_OUT){
		[ret addObjectsFromArray: [self convertEventScatter:event]];


	/* MPI Communicators */
	}else if ((type >= MPI_COMM_MIN && type <= MPI_COMM_MAX)
			|| type == MPI_COMM_GET_NAME_IN
			|| type == MPI_COMM_GET_NAME_OUT
			|| type == MPI_COMM_SET_NAME_IN
			|| type == MPI_COMM_SET_NAME_OUT){
//		[ret addObjectsFromArray:[self convertEventCommunicators:event]];
		
	/**
	 * OTHERS
	 * 
	 */
	}else if (type == MPI_OP_CREATE_IN
	||type == MPI_OP_FREE_IN
	||type == MPI_SCAN_IN
	||type == MPI_ATTR_DELETE_IN
	||type == MPI_ATTR_GET_IN
	||type == MPI_ATTR_PUT_IN
	|| (type >= MPI_GROUP_MIN && type <= MPI_GROUP_MAX)
	|| (type >= MPI_TYPE_MIN && type <= MPI_TYPE_MAX)
	|| (type >= MPI_CART_MIN && type <= MPI_CART_MAX)
	|| (type >= MPI_CART2_MIN && type <= MPI_CART2_MAX)
	|| (type >= MPI_GRAPH_MIN && type <= MPI_GRAPH_MAX)
	||type == MPI_INTERCOMM_CREATE_IN
	||type == MPI_INTERCOMM_MERGE_IN
	||type == MPI_KEYVAL_CREATE_IN
	||type == MPI_KEYVAL_FREE_IN
	||type == MPI_ABORT_IN
	||type == MPI_GET_PROCESSOR_NAME_IN
	||type == MPI_INITIALIZED_IN
	||type == MPI_WTICK_IN
	||type == MPI_WTIME_IN
	||type == MPI_ADDRESS_IN
	||type == MPI_BUFFER_ATTACH_IN
	||type == MPI_BUFFER_DETACH_IN
	||type == MPI_CANCEL_IN
	||type == MPI_REQUEST_FREE_IN
	||type == MPI_GET_ELEMENTS_IN
	||type == MPI_GET_COUNT_IN
	||type == MPI_IPROBE_IN
	||type == MPI_PACK_IN
	||type == MPI_PACK_SIZE_IN
	||type == MPI_PROBE_IN
	||type == MPI_START_IN
	||type == MPI_STARTALL_IN
	||type == MPI_TEST_IN
	||type == MPI_TESTALL_IN
	||type == MPI_TESTANY_IN
	||type == MPI_TEST_CANCELLED_IN
	||type == MPI_TESTSOME_IN
	||type == MPI_UNPACK_IN
	||type == MPI_DIMS_CREATE_IN
	||type == MPI_TOPO_TEST_IN
	||type == MPI_RECV_IDLE_IN
		|| type == MPI_OP_CREATE_OUT
		|| type == MPI_OP_FREE_OUT
		|| type == MPI_SCAN_OUT
		|| type == MPI_ATTR_DELETE_OUT
		|| type == MPI_ATTR_GET_OUT
		|| type == MPI_ATTR_PUT_OUT
		|| type == MPI_INTERCOMM_CREATE_OUT
		|| type == MPI_INTERCOMM_MERGE_OUT
		|| type == MPI_KEYVAL_CREATE_OUT
		|| type == MPI_KEYVAL_FREE_OUT
		|| type == MPI_ABORT_OUT
		|| type == MPI_GET_PROCESSOR_NAME_OUT
		|| type == MPI_INITIALIZED_OUT
		|| type == MPI_WTICK_OUT
		|| type == MPI_WTIME_OUT
		|| type == MPI_ADDRESS_OUT
		|| type == MPI_BUFFER_ATTACH_OUT
		|| type == MPI_BUFFER_DETACH_OUT
		|| type == MPI_CANCEL_OUT
		|| type == MPI_REQUEST_FREE_OUT
		|| type == MPI_GET_ELEMENTS_OUT
		|| type == MPI_GET_COUNT_OUT
		|| type == MPI_IPROBE_OUT
		|| type == MPI_PACK_OUT
		|| type == MPI_PACK_SIZE_OUT
		|| type == MPI_PROBE_OUT
		|| type == MPI_START_OUT
		|| type == MPI_STARTALL_OUT
		|| type == MPI_TEST_OUT
		|| type == MPI_TESTALL_OUT
		|| type == MPI_TESTANY_OUT
		|| type == MPI_TEST_CANCELLED_OUT
		|| type == MPI_TESTSOME_OUT
		|| type == MPI_UNPACK_OUT
		|| type == MPI_DIMS_CREATE_OUT
		|| type == MPI_TOPO_TEST_OUT
		|| type == MPI_RECV_IDLE_OUT){

			NSLog (@"others");
		[ret addObjectsFromArray: [self convertEventOthers:event]];


	/**
	 * ALL
	 * 
	 */
	}else if (type == MPI_ALLTOALL_IN
	 || type == MPI_ALLTOALLV_IN
	 || type == MPI_BARRIER_IN
		|| type == MPI_ALLTOALL_OUT
		|| type == MPI_ALLTOALLV_OUT
		|| type == MPI_BARRIER_OUT){

		[ret addObjectsFromArray: [self convertEventAll:event]];

	}
/*
	}else if (type == 4){
	}else{
		//eventos que não servem para nada, até agora
		//fprintf (stderr, "%@ %@ %@ %@\n", [event thread], [event description], [event machine], [event type]);

	}
*/
	[ret autorelease];
	return ret;
}

- (void) dealloc
{

	[super dealloc];
}
@end
